#include "lcd_draw.h"
/*
 * framebuffer application code, the start code of Linux GUI application
 * compile :
 *          $/usr/local/arm/2.95.3/bin/arm-linux-gcc -o fbtest fbtest.c
 *          $cp fbtest /tftpboot/examples
 * run in target:
 *          #mount 192.168.1.180:/tftpboot/ /mnt/nfs
 *          #cd /mnt/nfs/examples
 *          #./fbtest
 */

char *fbp = 0;
long int screensize = 0;
int fbfd = 0;
int x,y;
int xmax = 1024, ymax = 768;


/*画某一个像素点*/
void PutPixel(unsigned int x,unsigned int y,unsigned int c)
{
    if(x<xmax && y<ymax) {
    	*(fbp + y * xmax*2 + x *2) = 0x00FF&c;
    	*(fbp + y * xmax*2 + x *2 +1) = (0xFF00&c)>>8;
    }
}


/*屏幕初始化*/
void lcd_init(){


    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;

    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);

    if (!fbfd) {
        printf("Error: cannot open framebuffer device.\n");
        exit(1);
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
        printf("Error reading fixed information.\n");
        exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
        printf("Error reading variable information.\n");
        exit(3);
    }

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    printf("%dx%d, %dbpp, screensize = %ld\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel, screensize );

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                       fbfd, 0);
    if ((int)fbp == -1) {
        printf("Error: failed to map framebuffer device to memory.\n");
        exit(4);
    }
    printf("The framebuffer device was mapped to memory successfully.\n");


}

/*全屏变黑*/
void lcd_drawBlack(){
    printf("Black Screen\n");
    for(y = 0; y < 768; y++)
    {
        for(x = 0; x < 1024; x++)
        {
            *(fbp + y * 1024*2 + x*2) = 0x00;
            *(fbp + y * 1021*2 + x*2 +1) = 0x00;
        }
    }

}

/*全屏变蓝*/
void lcd_drawBlue(){
    printf("Blue Screen\n");
    for(y = 0; y < 768; y++)
    {
        for(x = 0; x < 1024; x++)
        {
            *(fbp + y * 1024*2 + x*2) = 0x1F;
            *(fbp + y * 1024*2 + x*2 +1) = 0x00;
        }
    }
}



/*画图片向上
**length:图片的长度
**width:图片的宽度
**initial_x:图片显示的起始位置的横坐标
**initial_y:图片显示的起始位置的纵坐标
*/
void lcd_drawPic_up(int length, int width, int initial_x, int initial_y, unsigned char *A){
        int k;
        k = 0;
        for(y = initial_y; y < width + initial_y; y++){

            for(x = initial_x; x < length + initial_x; x++)
            {
                *(fbp + y * 1024*2 + x*2) = A[k];
                *(fbp + y * 1024*2 + x*2 +1) = A[k+1];
                k+=2;
            }

    }
}

/*画向下图片
**length:图片的长度
**width:图片的宽度
**initial_x:图片显示的起始位置的横坐标
**initial_y:图片显示的起始位置的纵坐标
*/
void lcd_drawPic_down(int length, int width, int initial_x, int initial_y, unsigned char *A){
        int k;
        k = 0;
        for(y = initial_y; y < width + initial_y; y++){

            for(x = initial_x; x < length + initial_x; x++)
            {
                *(fbp + y * 1024*2 + x*2) = A[6240 - k];
                *(fbp + y * 1024*2 + x*2 +1) = A[6240 - (k+1)];
                k+=2;
            }

    }
}

/*画向左图片
**length:图片的长度
**width:图片的宽度
**initial_x:图片显示的起始位置的横坐标
**initial_y:图片显示的起始位置的纵坐标
*/
void lcd_drawPic_left(int length, int width, int initial_x, int initial_y, unsigned char *A){
        int k;
        k = 0;
        for(y = initial_y; y < width + initial_y; y++){

            for(x = initial_x; x < length + initial_x; x++)
            {
                *(fbp + y * 1024*2 + x*2) = A[k];
                *(fbp + y * 1024*2 + x*2 +1) = A[k+1];
                k+=2;
            }

    }
}

/*画向右图片
**length:图片的长度
**width:图片的宽度
**initial_x:图片显示的起始位置的横坐标
**initial_y:图片显示的起始位置的纵坐标
*/
void lcd_drawPic_right(int length, int width, int initial_x, int initial_y, unsigned char *A){
        int k;
        k = 0;
        for(y = initial_y; y < width + initial_y; y++){

            for(x = initial_x; x < length + initial_x; x++)
            {
                *(fbp + y * 1024*2 + x*2) = A[6240 - k];
                *(fbp + y * 1024*2 + x*2 +1) = A[6240 - (k+1)];
                k+=2;
            }

    }
}



/*功能:给某个区域变成一种颜色
**initialX:长方形的左上顶点横坐标
**initialY:长方形的左上顶点众坐标
**lastX:长方形的右下顶点横坐标
**lastY:长方形的右下顶点众坐标
*/
void lcd_drawRegionBlack(int initialX, int initialY, int lastX, int lastY){
    if((initialX >= 0) && (initialX < 1024) && (initialY >= 0) && (initialY < 768)
        && (lastX >= 0) && (lastX < 1024) && (lastY >= 0) && (lastY < 768)){
        for(y = initialY; y < lastY; y++){
            for(x = initialX; x < lastX; x++){
                *(fbp + y * 1024*2 + x*2) = 0x00;
                *(fbp + y * 1024*2 + x*2 +1) = 0x00;
            }
        }
    }
}



/*功能:给某个区域变成一种颜色
**initialX:长方形的左上顶点横坐标
**initialY:长方形的左上顶点众坐标
**lastX:长方形的右下顶点横坐标
**lastY:长方形的右下顶点众坐标
*/
void lcd_drawRegionRed(int initialX, int initialY, int lastX, int lastY){
    if((initialX >= 0) && (initialX < 1024) && (initialY >= 0) && (initialY < 768)
        && (lastX >= 0) && (lastX < 1024) && (lastY >= 0) && (lastY < 768)){
        for(y = initialY; y < lastY; y++){
            for(x = initialX; x < lastX; x++){
                *(fbp + y * 1024*2 + x*2) = 0x00;
                *(fbp + y * 1024*2 + x*2 +1) = 0xF8;
            }
        }
    }

}



/*清除内存，熄屏*/
void lcd_close(){

    munmap(fbp, screensize);
    close(fbfd);
}
